package com.hileto.inf.utils.dao;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;

import com.hileto.inf.utils.ObjectHelp;

/**
 * Copyright: Copyright (c) 2012 深圳市海乐淘电子商务有限公司
 * 
 * @Author : 曾林宝
 * @CreateTime : 2013-1-21 上午09:56:06
 * 
 * @Description: 实体映射与sql工具类.
 */
public class Entity {
	private Class<?> entityClazz; //实体类
	private String tableName;
	private String idFieldName;
	private Field idField;
	private Field[] fields;
	private LinkedList<Field> noIdFieldLst = new LinkedList<Field>();
	private RowMapper<?> rowMapper;
	private String insertSql;
	private String updateSql;
	private String deleteSql;

	public Entity(Class<?> entityClazz) {
		if(doProccessId()){
			this.entityClazz = entityClazz;
			doProccessTableName();
			rowMapper = ParameterizedBeanPropertyRowMapper.newInstance(entityClazz);
		}
	}

	/**
	 * @Description : 处理ID
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:13:07
	 */
	private boolean doProccessId() {
		fields = entityClazz.getDeclaredFields();
		boolean isFound = false;
		for (Field field : fields) {
			if (!isFound
					&& null != field.getAnnotation(javax.persistence.Id.class)) {
				idFieldName = field.getName();
				idField = field;
				isFound = true;
			} else {
				noIdFieldLst.add(field);
			}
		}
		return isFound;
	}

	/**
	 * @Description : 获取表名
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:13:16
	 */
	private void doProccessTableName() {
		javax.persistence.Entity entity = entityClazz
				.getAnnotation(javax.persistence.Entity.class);
		javax.persistence.Table table = entityClazz
				.getAnnotation(javax.persistence.Table.class);
		String tableName = entityClazz.getSimpleName();
		if (null != entity) {
			String tmp = null;
			if (ObjectHelp.isNotEmpty(tmp = table.name())) {
				tableName = tmp;
			}
			if (ObjectHelp.isNotEmpty(tmp = entity.name())) {
				tableName = tmp;
			}
		}
		this.tableName = tableName;
	}

	public Class<?> getEntityClazz() {
		return entityClazz;
	}

	public String getTableName() {
		return tableName;
	}

	public String getIdFieldName() {
		return idFieldName;
	}

	public Field getIdField() {
		return idField;
	}

	public Field[] getFields() {
		return fields;
	}

	public LinkedList<Field> getNoIdFieldLst() {
		return noIdFieldLst;
	}

	/**
	 * @Description : 生成标准INSERT INTO SQL.
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:13:35
	 * @return
	 */
	public String generateInsertSQL() {
		if (ObjectHelp.isEmpty(insertSql)) {
			StringBuilder sb1 = new StringBuilder();
			StringBuilder sb2 = new StringBuilder();
			sb1.append("insert into ").append(this.tableName).append(" (");
			sb2.append(") values (");

			Field[] fields = this.fields;
			String key = null;
			String fieldName = null;
			for (Field field : fields) {
				fieldName = field.getName();
				if ("serialVersionUID".equals(fieldName)) {
					continue;
				}
				sb1.append(fieldName).append(", ");
				key = ":" + fieldName;
				sb2.append(key).append(", ");
			}
			sb1.delete(sb1.lastIndexOf(","), sb1.length());
			sb2.delete(sb2.lastIndexOf(","), sb2.length());
			sb1.append(sb2).append(")");
			insertSql = sb1.toString();
		}
		return insertSql;
	}

	/**
	 * @Description : 生成标准UPDATE SET SQL.全字段. update T set .... where id = :id
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:14:12
	 * @return
	 */
	public String generateUpdateSQL() {
		if (ObjectHelp.isEmpty(updateSql)) {
			StringBuilder sb = new StringBuilder().append("update ")
					.append(this.tableName).append(" set ");

			LinkedList<Field> fieldTmp = this.noIdFieldLst;
			for (Iterator<Field> it = fieldTmp.iterator(); it.hasNext();) {
				String key = it.next().getName();
				sb.append(key).append(" = ").append(":").append(key);
				if (it.hasNext()) {
					sb.append(", ");
				}
			}
			sb.append(" where " + idFieldName);
			sb.append(" = :" + idFieldName);
			updateSql = sb.toString();
		}
		return updateSql;
	}

	/**
	 * @Description : 生成标准DELETE SQL , delete from T where id = :id
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:15:50
	 * @return
	 */
	public String generateDeleteSQL() {
		if (ObjectHelp.isEmpty(deleteSql)) {
			StringBuilder sb = new StringBuilder().append("delete from ")
					.append(getTableName());
			sb.append(" where ").append(idFieldName).append(" = ").append(":")
					.append(idFieldName);
		}
		return deleteSql;
	}
	
	/**
	 * @Description : 生成标准DELETE SQL. delete from T where id = ?.
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:16:38
	 * @return
	 */
	public String generateDeleteSQLByID() {
			StringBuilder sb = new StringBuilder().append("delete from ")
					.append(getTableName());
			sb.append(" where ").append(idFieldName).append(" = ?");
			return sb.toString();
	}

	/**
	 * @Description : 生成动态删除SQL.
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:17:39
	 * @param conditions 条件map.
	 * @param conditionsExt 其它.
	 * @return
	 */
	public String generateDeleteSQL(Map<String, Object> conditions,
			String conditionsExt) {
		StringBuilder sb = new StringBuilder().append(" delete from ")
				.append(getTableName()).append(" where 1 = 1 ");
		if ((conditions != null) && (conditions.size() == 0)) {
			for (Iterator<String> it = conditions.keySet().iterator(); it
					.hasNext();) {
				String key = it.next();
				sb.append(" and ").append(key).append(" = ").append(":")
						.append(key);
			}
		}
		if (ObjectHelp.isNotEmpty(conditionsExt)) {
			sb.append(" ").append(conditionsExt);
		}
		return sb.toString();
	}

	/**
	 * @Description : 动态查询SQL.
	 * @Author : 曾林宝
	 * @CreateTime : 2013-1-22 上午09:18:00
	 * @param conditions 条件map.
	 * @param conditionsExt 其它,如limit 10.
	 * @return
	 */
	public String getSelectSql(Map<String, Object> conditions,
			String conditionsExt) {
		StringBuilder sb = new StringBuilder().append(" select * from ")
		.append(this.getTableName()).append(" where 1 = 1 ");
		if(ObjectHelp.isNotEmpty(conditions)){
			for (Entry<String, Object> entry : conditions.entrySet()) {
				String key = entry.getKey();
				sb.append(" and ").append(key).append(" = ").append(":")
						.append(key);
			}
		}
		if (ObjectHelp.isNotEmpty(conditionsExt)) {
			sb.append(" ").append(conditionsExt);
		}
		return sb.toString();
	}

	@SuppressWarnings("all")
	public RowMapper getRowMapper() {
		return rowMapper;
	}

	public String generateSelectSQLByID() {
		StringBuilder sball = new StringBuilder(30).append(" select * from ")
		.append(this.getTableName());
		sball.append(" where " + idFieldName + " = ? limit 1");
		return sball.toString();
	}	
}
